package cn.pugle.mianshi.ali20180125;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 题目二：
 * 有一个商品套餐Combo对象，套餐内包含3个商品List<Product>，分别叫A,B,C，
 * 商品对象内有一个public+long+getPrice()的方法获取商品的价格，
 * 商品信息通过另外一个ProductService接口的public+Product+queryInfo(id)函数来获取。
 * <p>
 * 1.+现在要求开三个线程，并行完成对商品组合内三个商品的信息查询，
 * 2.+要求执行顺序A先于B，B先于C
 * 3.+商品信息取到后，输出套餐的总价（三个商品价格之和）
 *
 * @author tzp
 * @since 2018/1/25
 */
public class ThreadCountTest {
    private final Object lock = new Object();
    private int current = 0;
    private CountDownLatch countDownLotch;//这个类的api记不清楚了
    private ProductService productService = new ProductService();
    private Long sumPrice = 0L;

    public static void main(String[] args) throws InterruptedException {
        new ThreadCountTest().test();
    }

    public void test() throws InterruptedException {
        List<Product> products = new ArrayList<Product>() {{
            add(new Product(1L, 10L));
            add(new Product(2L, 100L));
            add(new Product(3L, 1000L));
            add(new Product(3L, 1000L));
            add(new Product(3L, 1000L));
            add(new Product(3L, 1000L));
            add(new Product(3L, 1000L));
        }};
        countDownLotch = new CountDownLatch(products.size());

        for (int i = 0; i < products.size(); i++) {
            Thread thread = new ProductQueryThread(products.get(i), i);
            thread.start();
        }

        countDownLotch.await();
        System.out.println("SumPrice: " + sumPrice);
    }

    private static class Product {
        public Product(Long id, Long price) {
            this.id = id;
            this.price = price;
        }

        private Long id;
        private Long price;

        public Long getId() {
            return id;
        }

        public Product setId(Long id) {
            this.id = id;
            return this;
        }

        public Long getPrice() {
            return price;
        }

        public Product setPrice(Long price) {
            this.price = price;
            return this;
        }
    }

    private static class ProductService {
        public Product queryInfo(Long id) {
            return new Product(id, 10L);
        }
    }

    class ProductQueryThread extends Thread {
        private Product product;
        private int index;

        public ProductQueryThread(Product product, int index) {
            this.product = product;
            this.index = index;
        }

        @Override
        public void run() {
            synchronized (lock) {
                while (current != index) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(index + " out of loop. running");
                Product product = productService.queryInfo(this.product.getId());
                //do sth
                sumPrice += product.getPrice();
                current++;
                lock.notifyAll();
            }
            countDownLotch.countDown();
        }
    }
}
